#ifndef _ECHO_PARSER_
#define _ECHO_PARSER_
#include <iostream>
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <assert.h>
#include "tinyxml.h"
#include <vector>
#include <map>
#include "Segment.h"
#include "BeatObject.h"

//Forward declaration of EchoParser for the EchoParserVisitor
class EchoParser;

/**
TODO:
	* Change usage of floats to doubles. That includes the
		helper functions that parse C strings from the XML
		file into a specific datatype (using sscanf). Doubles would
		be a bit more accurate in our case
**/
using namespace std;

class EchoParserVisitor : public TiXmlVisitor
{
	public:
		EchoParserVisitor();
		bool VisitEnter(const TiXmlDocument &);
		bool VisitExit(const TiXmlDocument &);
		bool VisitEnter(const TiXmlElement &, const TiXmlAttribute*);
		bool VisitExit(const TiXmlElement &);
		bool isVisitingSegment();
		void setParser(EchoParser* p);
		float str2float(const char* str);
		
	private:
		bool m_isVisitingSegment;
		EchoParser* m_parser; //pointer to EchoParser that contains this
		int m_nextSegmentId;
		Segment* m_currentSegment;
};

class EchoParser
{
	public:
		EchoParser();
		virtual ~EchoParser();
		int readXmlFile(const char* path);
		void print();
		void process();
		vector<Segment*>* getSegments();
		std::vector<BeatObject*>* getBeatObjects(int difficulty);
		std::vector<float>* getSectionStarts();
		std::vector<float>* getSectionDurations();
		
		
		//Generic (Internal) Modifiers
		/*
		TODO: Better design would be to use the C++
		friend functionality to make this available to 
		the EchoParserVisitor
		*/
		
		float getScalarAttr(string key);
		float* getVectorAttr(string key);
		void setScalarAttr(string key, float value);
		void setVectorAttr(string key, float* value);
		void setTatums(float* tatums);
		void setTatum(int i, float tatum);
		float* getTatums();
		int getNumTatums();
		float getTatum(int i);
		int getAverageTatumsPerSegment();
		
		
		
	private:
	
		
		/*
		Song Information
		*/
		
		//Scalar Members
		std::map<string, float>* m_scalar_attr;
		
		//Vector Members
		std::map<string, float*>* m_vector_attr;
		std::vector<BeatObject*>* m_beatObjects;
		std::vector<Segment*>* m_segments;
		std::vector<float>* m_section_starts;
		std::vector<float>* m_section_durations;
		float* m_tatums;
		
		
		
		/*
		Parser Information
		*/
		TiXmlDocument* m_document;
		EchoParserVisitor* m_visitor;
		
};


#endif